package com.bee.web.token;

import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;

import com.bee.web.security.AES;
import com.bee.web.util.StringUtil;

/**
 * 用户Token管理类
 *
 * @author liuzy
 * @since 2015年6月12日
 */
public class TokenManager {

    private Logger logger = Logger.getLogger(TokenManager.class);

    public ConcurrentHashMap<String, Token> tokenMap = new ConcurrentHashMap<String, Token>();

    /**
     * Token有效期:默认1小时
     */
    private int expiredTime = 1000 * 60 * 60;

    /**
     * Token加密密钥
     */
    private String secretKey = "liuzy";

    private Timer timer = new Timer();

    /**
     * 重新生成用户Token,用户旧Token过期
     *
     * @param token
     * @return
     */
    public String createToken(String userId) {
        if (tokenMap.containsKey(userId)) {
            tokenMap.remove(userId);
        }
        long time = System.currentTimeMillis();
        Token tokenObj = new Token(AES.encrypt(userId + time, secretKey), time);
        tokenMap.put(userId, tokenObj);
        return tokenObj.getToken();
    }

    /**
     * 取得用户Token对象
     *
     * @param userId
     * @return
     */
    public Token getToken(String userId) {
        return tokenMap.get(userId);
    }

    /**
     * 验证Token有效性
     *
     * @param token
     * @return
     */
    public boolean isToken(String token) {
        if (StringUtil.isNullOrEmpty(token)) {
            return false;
        }
        String userId = token2userId(token);
        if (userId != null && tokenMap.containsKey(userId) && tokenMap.get(userId).getToken().equals(token)) {
            tokenMap.get(userId).setTime(System.currentTimeMillis());
            return true;
        }
        return false;
    }

    /**
     * 删除用户Token,使其失效
     *
     * @param token
     */
    public void removeToken(String token) {
        tokenMap.remove(token2userId(token));
    }

    /**
     * 从Token中解密出用户ID
     *
     * @param token
     * @return
     */
    public String token2userId(String token) {
        try {
        	String str = AES.decrypt(token, secretKey);
        	String userId = str.substring(0, str.length() - (System.currentTimeMillis() + "").length());
        	return userId;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Spring管理的启动方法
     */
    public void start() {
        timer.schedule(new TimerTask() {
            public void run() {
                for (Entry<String, Token> entry : tokenMap.entrySet()) {
                    if (System.currentTimeMillis() - entry.getValue().getTime() >= expiredTime) {
                        logger.info("用户[" + entry.getKey() + "]令牌过期");
                        tokenMap.remove(entry.getKey());
                    }
                }
                logger.info("在线用户:" + tokenMap.size());
            }
        }, expiredTime, expiredTime);
    }

    /**
     * Spring管理的销毁方法
     */
    public void destroy() {
        // 清空cache
        tokenMap.clear();
        // 停止定时器任务
        timer.cancel();
    }

    public int getExpiredTime() {
        return expiredTime;
    }

    public void setExpiredTime(int expiredTime) {
        this.expiredTime = expiredTime;
    }

    public String getSecretKey() {
        return secretKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

}
